import { buildStorage } from "./StorageHelpers";
import { Contract, RawStorageEntry } from "./index";
import safeContracts from "./safe-contracts.json";
import { BridgeDoorContractAddress } from "./BridgeDoorContract";
import keccak256 from "keccak256";

export const XrpSafeContractAddress = `0x${keccak256(Buffer.from("xrp_bridge")).slice(-20).toString("hex")}`;

export const XrpSafeContract = (owners: string[], threshold: number): Contract => ({
    address: XrpSafeContractAddress,
    bytecode:
        "608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea2646970667358221220d1429297349653a4918076d650332de1a1068c5f3e07c5c82360c277770b955264736f6c63430007060033",
    memory: buildSafeStorage(owners, threshold, [BridgeDoorContractAddress]),
});

export const buildSentinel = (addresses: string[]): Record<string, string> => {
    const sentinel = "0x0000000000000000000000000000000000000001";
    let currentOwner = sentinel;
    const result: Record<string, string> = {};
    for (let i = 0; i < addresses.length; i++) {
        result[currentOwner] = addresses[i];
        currentOwner = addresses[i];
    }
    result[currentOwner] = sentinel;
    return result;
};

const buildSafeStorage = (owners: string[], threshold: number, modules: string[]): RawStorageEntry[] => {
    const safeMasterAddress = safeContracts.find((contract) => contract.name === "GnosisSafeL2")!.address;
    const fallbackHandlerAddress = safeContracts.find((contract) => contract.name === "CompatibilityFallbackHandler")!.address;
    return [
        ...buildStorage({
            slot: 0,
            value: safeMasterAddress,
        }),
        ...buildStorage({
            slot: 1,
            value: buildSentinel(owners),
        }),
        ...buildStorage({
            slot: 2,
            value: buildSentinel(modules),
        }),
        ...buildStorage({
            slot: 3,
            value: owners.length,
        }),
        ...buildStorage({
            slot: 4,
            value: threshold,
        }),
        ...buildStorage({
            slot: "6c9a6c4a39284e37ed1cf53d337577d14212a4870fb976a4366c693b939918d5",
            value: fallbackHandlerAddress,
        }),
    ];
};
